package org.pay.service.impl;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.pay.core.common.Exception.ServiceException;
import org.pay.core.common.constant.MchConstant;
import org.pay.core.common.constant.RetEnum;
import org.pay.core.common.util.MyLog;
import org.pay.core.entity.MchAccount;
import org.pay.core.entity.MchBankAccount;
import org.pay.core.entity.MchSettRecord;
import org.pay.core.entity.MchSettRecordExample;
import org.pay.core.service.IMchAccountService;
import org.pay.core.service.IMchBankAccountService;
import org.pay.core.service.IMchSettHandleService;
import org.pay.service.dao.mapper.MchSettRecordMapper;

import java.util.Date;
import java.util.List;

/**
 * @author: yangshancheng
 * @date: 17/12/7
 * @description:
 */
@Service
public class MchSettHandleServiceImpl implements IMchSettHandleService {

    @Autowired
    private MchSettRecordMapper mchSettRecordMapper;

    @Autowired
    private IMchAccountService mchAccountService;

    @Autowired
    private IMchBankAccountService mchBankAccountService;

    private static final MyLog _log = MyLog.getLog(MchSettHandleServiceImpl.class);

    @Override
    public int applySett(Long mchId, Long bankAccountId, Long settAmount) {
        // 查询商户账户信息,判断金额是否够结算
        MchAccount mchAccount = mchAccountService.findByMchId(mchId);
        if(mchAccount == null) {
            // 账户不存在
            throw ServiceException.build(RetEnum.RET_SERVICE_ACCOUNT_NOT_EXIST);
        }
        // 可结算金额
        Long availableAmount = mchAccount.getAvailableSettAmount();
        if(settAmount.compareTo(availableAmount) > 0) {
            // 金额超限
            throw ServiceException.build(RetEnum.RET_SERVICE_SETT_AMOUNT_NOT_SETT);
        }
        // 获取用户银行账号
        MchBankAccount mchBankAccount = mchBankAccountService.findById(bankAccountId);
        if(mchBankAccount == null) {
            // 银行账号不存在
            throw ServiceException.build(RetEnum.RET_SERVICE_BANK_ACCOUNT_NOT_EXIST);
        }
        // 结算记录
        MchSettRecord settRecord = new MchSettRecord();
        settRecord.setMchId(mchId);
        settRecord.setName(mchAccount.getName());
        settRecord.setSettMode(MchConstant.SETT_MODE_HAND);
        settRecord.setMchType(mchAccount.getKind());
        settRecord.setSettDate(new Date());
        settRecord.setSettAmount(settAmount);
        settRecord.setSettFee(0l);
        settRecord.setRemitAmount(settAmount);
        settRecord.setRemitType(mchBankAccount.getAccountType());
        settRecord.setMchRemitInfo(mchBankAccount.getAccountNo());
        settRecord.setSettStatus(MchConstant.SETT_STATUS_AUDIT_ING);
        settRecord.setRemark("");
        settRecord.setRemitRemark("");

        int insertCount = mchSettRecordMapper.insertSelective(settRecord);

        // 冻结资金操作
        mchAccountService.freezeAmount(mchId, settAmount);

        return insertCount;


    }

    @Override
    public List<MchSettRecord> select(int offset, int limit, MchSettRecord mchSettRecord) {
        MchSettRecordExample example = new MchSettRecordExample();
        example.setOrderByClause("create_time desc");
        example.setOffset(offset);
        example.setLimit(limit);
        MchSettRecordExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, mchSettRecord);
        return mchSettRecordMapper.selectByExample(example);
    }

    @Override
    public List<MchSettRecord> select(int offset, int limit, List<Byte> settStatusList, MchSettRecord mchSettRecord) {
        MchSettRecordExample example = new MchSettRecordExample();
        example.setOrderByClause("create_time desc");
        example.setOffset(offset);
        example.setLimit(limit);
        MchSettRecordExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, mchSettRecord);
        criteria.andSettStatusIn(settStatusList);
        return mchSettRecordMapper.selectByExample(example);
    }

    @Override
    public int count(MchSettRecord mchSettRecord) {
        MchSettRecordExample example = new MchSettRecordExample();
        MchSettRecordExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, mchSettRecord);
        return mchSettRecordMapper.countByExample(example);
    }

    @Override
    public int count(List<Byte> settStatusList, MchSettRecord mchSettRecord) {
        MchSettRecordExample example = new MchSettRecordExample();
        MchSettRecordExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, mchSettRecord);
        criteria.andSettStatusIn(settStatusList);
        return mchSettRecordMapper.countByExample(example);
    }

    @Override
    public int auditSett(Long id, Byte status, String remark) {

        MchSettRecord mchSettRecord = mchSettRecordMapper.selectByPrimaryKey(id);

        if(mchSettRecord == null) {
            throw ServiceException.build(RetEnum.RET_SERVICE_SETT_RECORD_NOT_EXIST);
        }

        // 状态必须为审核中或审核不通过
        if(!mchSettRecord.getSettStatus().equals(MchConstant.SETT_STATUS_AUDIT_ING) &&
                !mchSettRecord.getSettStatus().equals(MchConstant.SETT_STATUS_AUDIT_NOT)) {
            throw ServiceException.build(RetEnum.RET_SERVICE_SETT_STATUS_ERROR);
        }

        MchSettRecordExample example = new MchSettRecordExample();
        MchSettRecordExample.Criteria criteria = example.createCriteria();
        MchSettRecord updateMchSettRecord = new MchSettRecord();
        updateMchSettRecord.setSettStatus(status);
        updateMchSettRecord.setRemark(remark);
        criteria.andIdEqualTo(id);
        //criteria.andSettStatusEqualTo(MchConstant.SETT_STATUS_AUDIT_ING);
        int updateCount = mchSettRecordMapper.updateByExampleSelective(updateMchSettRecord, example);

        // 审核不通过,需要解冻金额
        if(updateCount == 1 && status == MchConstant.SETT_STATUS_AUDIT_NOT) {
            mchAccountService.unFreezeSettAmount(mchSettRecord.getMchId(), mchSettRecord.getSettAmount());
        }

        return updateCount;
    }

    @Override
    public MchSettRecord findByMchIdAndId(Long mchId, Long id) {
        MchSettRecordExample example = new MchSettRecordExample();
        MchSettRecordExample.Criteria criteria = example.createCriteria();
        criteria.andMchIdEqualTo(mchId);
        criteria.andIdEqualTo(id);
        List<MchSettRecord> mchSettRecordList = mchSettRecordMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(mchSettRecordList)) return null;
        return mchSettRecordList.get(0);
    }

    @Override
    public MchSettRecord findById(Long id) {
        return mchSettRecordMapper.selectByPrimaryKey(id);
    }

    @Override
    public int remit(Long id, Byte status, String remark, String remitRemark) {

        MchSettRecord mchSettRecord = mchSettRecordMapper.selectByPrimaryKey(id);

        if(mchSettRecord == null) {
            throw ServiceException.build(RetEnum.RET_SERVICE_SETT_RECORD_NOT_EXIST);
        }
        // 状态必须为审核成功|打款中|打款失败
        if(!mchSettRecord.getSettStatus().equals(MchConstant.SETT_STATUS_AUDIT_OK) &&
                !mchSettRecord.getSettStatus().equals(MchConstant.SETT_STATUS_REMIT_ING) &&
                !mchSettRecord.getSettStatus().equals(MchConstant.SETT_STATUS_REMIT_FAIL)) {
            throw ServiceException.build(RetEnum.RET_SERVICE_SETT_STATUS_ERROR);
        }

        MchSettRecordExample example = new MchSettRecordExample();
        MchSettRecordExample.Criteria criteria = example.createCriteria();
        MchSettRecord updateMchSettRecord = new MchSettRecord();
        updateMchSettRecord.setSettStatus(status);
        updateMchSettRecord.setRemark(remark);
        updateMchSettRecord.setRemitRemark(remitRemark);
        criteria.andIdEqualTo(id);
        //criteria.andSettStatusEqualTo(MchConstant.SETT_STATUS_AUDIT_ING);
        int updateCount = mchSettRecordMapper.updateByExampleSelective(updateMchSettRecord, example);
        if(updateCount == 1) {
            if(status == MchConstant.SETT_STATUS_REMIT_FAIL) {
                // 打款失败,解冻金额
                mchAccountService.unFreezeSettAmount(mchSettRecord.getMchId(), mchSettRecord.getSettAmount());
            }else if(status == MchConstant.SETT_STATUS_REMIT_SUCCESS) {
                // 打款成功,解冻+减款
                mchAccountService.unFreezeAmount(mchSettRecord.getMchId(), mchSettRecord.getSettAmount(), String.valueOf(id), MchConstant.BIZ_TYPE_REMIT);
            }
        }

        return updateCount;
    }

    void setCriteria(MchSettRecordExample.Criteria criteria, MchSettRecord mchSettRecord) {
        if(mchSettRecord != null) {
            if(mchSettRecord.getMchId() != null) criteria.andMchIdEqualTo(mchSettRecord.getMchId());
            if(mchSettRecord.getId() != null) criteria.andIdEqualTo(mchSettRecord.getId());
            if(mchSettRecord.getSettStatus() != null && mchSettRecord.getSettStatus().byteValue() != -99) criteria.andSettStatusEqualTo(mchSettRecord.getSettStatus());
        }
    }

}
